package CIF::Message::Malware;
use base 'CIF::DBI';

use strict;
use warnings;

use XML::Malware;
use XML::IODEF;
use CIF::Message;
use CIF::Message::IODEF;

__PACKAGE__->table('malware');
__PACKAGE__->columns(Primary => 'id');
__PACKAGE__->columns(All => qw/id uuid description source hash_sha1 hash_md5 content impact confidence severity restriction alternativeid alternativeid_restriction detecttime created/);
__PACKAGE__->columns(Essential => qw/id uuid description hash_sha1 hash_md5 restriction created/);
__PACKAGE__->has_a(uuid   => 'CIF::Message');
__PACKAGE__->sequence('malware_id_seq');

sub insert {
    my $self = shift;
    my $info = {%{+shift}};
    
    my $uuid    = $info->{'uuid'};
    my $source  = $info->{'source'};
    $source = CIF::Message::genSourceUUID($source) unless(CIF::Message::isUUID($source));
    $info->{'source'} = $source;

    unless($uuid){
        $uuid = CIF::Message::IODEF->insert({
            message => $self->toIODEF($info),
        });
        $uuid = $uuid->uuid();
    }

    my $id = eval { $self->SUPER::insert({
        uuid    => $uuid,
        description => $info->{'description'},
        source      => $info->{'source'},
        hash_md5    => $info->{'hash_md5'},
        hash_sha1   => $info->{'hash_sha1'},
        content     => $info->{'content'},
        impact      => $info->{'impact'},
        confidence  => $info->{'confidence'},
        severity    => $info->{'severity'},
        restriction => $info->{'restriction'} || 'private',
        detecttime  => $info->{'detecttime'},
        alternativeid   => $info->{'alternativeid'},
        alternativeid_restriction => $info->{'alternativeid_restriction'} || 'private',
    }) };
    if($@){
        die $@ unless($@ =~ /duplicate key value violates unique constraint/);
        $id = $self->retrieve(uuid => $uuid);
    }
    return($id);
}

sub toIODEF {
    my $self = shift;
    my $info = {%{+shift}};

    my $relatedid   = $info->{'relatedid'};
    my $description = $info->{'description'};
    my $source      = $info->{'source'};
    my $hash_md5    = $info->{'hash_md5'};
    my $hash_sha1   = $info->{'hash_sha1'};
    my $content     = $info->{'content'};
    my $impact      = $info->{'impact'};
    my $confidence  = $info->{'confidence'};
    my $severity    = $info->{'severity'};
    my $restriction = $info->{'restriction'} || 'private';
    my $detecttime  = $info->{'detecttime'};
    my $alternativeid  = $info->{'alternativeid'};
    my $alternativeid_restriction = $info->{'alternativeid_restriction'} || 'private';

    my $h;
    $h->{'company'}     = $source;
    $h->{'author'}      = $source;
    $h->{'comment'}     = $description;
    $h->{'timestamp'}   = $detecttime;
    $h->{'id'}          = $hash_md5 || $hash_sha1 || '';

    push(@{$h->{'objects'}->{'file'}}, { id => $hash_md5, md5 => $hash_md5, sha1 => $hash_sha1 });
    push(@{$h->{'objects'}->{'classification'}}, { id => '', companyName => $source, type => 'dirty', classificationName => $impact});

    my $m = XML::Malware->new($h);
    
    my $iodef = XML::IODEF->new();
    $iodef->add('Incidentrestriction',$restriction);
    $iodef->add('IncidentDescription',$description);
    $iodef->add('IncidentIncidentIDname',$source);
    if($relatedid){
        $iodef->add('IncidentRelatedActivityIncidentID',$relatedid);
    }
    if($alternativeid){
        $iodef->add('IncidentAlternativeIDIncidentID',$alternativeid);
        $iodef->add('IncidentAlternativeIDIncidentIDrestriction',$alternativeid_restriction);
        $iodef->add('IncidentAlternativeIDIncidentIDname',$source);
    }
    $iodef->add('IncidentDetectTime',$detecttime) if($detecttime);
    $iodef->add('IncidentAssessmentImpact',$impact);
    $iodef->add('IncidentAssessmentConfidencerating','numeric');
    $iodef->add('IncidentAssessmentConfidence',$confidence);
    $iodef->add('IncidentAssessmentImpactseverity',$severity);

    
    # malware bits
    $iodef->add('IncidentEventDataRecordRecordDataRecordItemdtype','xml');
    $iodef->add('IncidentEventDataRecordRecordDataRecordItemmeaning','malware sample');
    $iodef->add('IncidentEventDataRecordRecordDataRecordItemformatid','icsg1.1');
    $iodef->add('IncidentEventDataRecordRecordDataRecordItemrestriction',$restriction);
    $iodef->add('IncidentEventDataRecordRecordDataRecordItem',$m->out());

    return($iodef->out());
}
1;

__END__
